package aochulai.qisiren;

import baseFx.common.Dynamic;
import baseFx.common.Stream;
import baseFx.common.utils.FxDate;
import baseFx.common.utils.StringUtils;
import baseFx.serialization.json.JsonUtils;
import baseFx.springboot.FxController;
import baseFx.springboot.anno.PathRestController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@PathRestController("game")
public class GameApi extends FxController {
    private static Logger logger = LoggerFactory.getLogger(GameApi.class);
    private static Map<String, Game> gameMap = new ConcurrentHashMap<>();
    private static Map<String, Player> playerMap = new ConcurrentHashMap<>();

    private static String success(Object data) {
        return JsonUtils.toJson(Dynamic.setNew(s -> {
            s.put("success", true);
            s.put("data", data);
        }));
    }

    private static String fail(String msg) {
        return JsonUtils.toJson(Dynamic.setNew(s -> {
            s.put("success", false);
            s.put("msg", msg);
        }));
    }

    public GameApi() {
        actionError.add((s, e) -> e.result = fail(e.error.getMessage()));
    }

    @RequestMapping("/")
    public Object index() {
        return new FxDate().format();
    }

    @RequestMapping("watch")
    public Object watch() {
        String id = getStringParam("pid").get();
        Player p = playerMap.get(id);
        List<String> list = new ArrayList<>(p.cmd);
        p.cmd.clear();
        return success(list);
    }

    @RequestMapping("login")
    public Object login() {
        String id = getStringParam("id").get();
        String name = getStringParam("name").orElse("无名氏");
        Player p = playerMap.get(id);
        if (p == null) {
            p = new Player();
            p.id = id;
            p.name = name;
            playerMap.put(p.id, p);
        }
        p.name = name;
        logger.info("已登录：{},{}", id, name);
        if (p.inGame != null) {
            return success(p.inGame.id);
        }
        return success("ok");
    }

    @RequestMapping("newgame")
    public Object newgame() {
        String pid = getStringParam("pid").get();
        Player p = playerMap.get(pid);
        Game game = new Game(p.name);
        gameMap.put(game.id, game);
        return success(game.id);
    }

    @RequestMapping("list")
    public Object list() {
        return success(Stream.create(gameMap.values()).map(i -> Dynamic.setNew(s -> {
            s.put("id", i.id);
            s.put("name", i.name);
            s.put("pc", i.players.count());
            s.put("started", i.started);
        })).toList());
    }

    @RequestMapping("add")
    public Object add() {
        String pid = getStringParam("pid").get();
        String gid = getStringParam("gid").get();
        Player p = playerMap.get(pid);
        Game g = gameMap.get(gid);
        if (g == null) {
            return fail("游戏房间已关闭");
        } else {
            g.add(p);
            return success(gid);
        }
    }

    @RequestMapping("leave")
    public Object leave() {
        String pid = getStringParam("pid").get();
        Player p = playerMap.get(pid);
        Game g = p.inGame;
        g.leave(p);
        if (g.players.count() == 0) {
            gameMap.remove(g.id);
        }
        return success("ok");
    }

    @RequestMapping("ready")
    public Object ready() {
        String pid = getStringParam("pid").get();
        Boolean isReady = getBoolParam("isready").get();
        Player p = playerMap.get(pid);
        p.inGame.ready(p, isReady);
        return success("ok");
    }

    @RequestMapping("chupai")
    public Object chupai() {
        String pid = getStringParam("pid").get();
        String pais = getStringParam("pai").orElse("");
        String wang = getStringParam("wang").orElse("");
        Player p = playerMap.get(pid);
        Integer[] plist = Stream.create(pais.split(",")).filter(StringUtils::hasValue).map(Integer::parseInt).toArray(Integer.class);
        String[] wlist = wang.split(",");
        p.inGame.chupai(p, plist, wlist);
        return success("ok");
    }

    @RequestMapping("pass")
    public Object pass() {
        String pid = getStringParam("pid").get();
        Player p = playerMap.get(pid);
        p.inGame.pass(p);
        return success("ok");
    }

    @RequestMapping("change")
    public Object change() {
        String pid = getStringParam("pid").get();
        String name = getStringParam("name").get();
        Player p = playerMap.get(pid);
        p.name = name;
        return success(name);
    }

    @RequestMapping("clear")
    public Object clear() {
        playerMap.clear();
        gameMap.clear();
        return success("已重置游戏服务器");
    }

    @RequestMapping("voice")
    public Object voice() {
        String pid = getStringParam("pid").get();
        String vid = getStringParam("vid").get();
        Player p = playerMap.get(pid);
        p.inGame.voice(p, vid);
        return success("ok");
    }
}
